/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rosic.GoogleMaps;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import com.sun.lwuit.Image;

/**
 *
 * @author David
 */
public class GoogleMaps {

     private static final String URL_UNRESERVED =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
        "abcdefghijklmnopqrstuvwxyz" +
        "0123456789-_.~";

     private static final char[] HEX = "0123456789ABCDEF".toCharArray();

      // these 2 properties will be used with map scrolling methods. You can remove them if not needed
    public static final int offset = 268435456;
    public static final double radius = offset / Math.PI;

    private String apiKey = null;
   /**
    * en este string se van armando los marcadores que se quieren mostrar
    */
    private String marcadores;
    /**
     * indica si se han agregado marcadores o no.
     */
    private boolean hayMarcadores;

    private String rutas;

     public GoogleMaps(String key) {
        apiKey = key;
        marcadores="";
        hayMarcadores=false;

        rutas ="";

        // rutas="&path=rgb:0x0000ff,weight:5|4.60104,-74.06923|4.60304,-74.06923|4.60704,-74.06123|";
    }
      /**
       * agrega un marcador rojo al string de marcadores
       * @param latitud latitud del marcador
       * @param longitud longitud del marcador
       * @param letra letra a mostrar en el marcador, también puede ser un número. 
       */
     public void agregarMarcadorRojo(double latitud, double longitud, char letra){
         if(!hayMarcadores){
             marcadores="&markers=";
             hayMarcadores=true;
         }
         
         marcadores+= latitud+","+longitud+","+"red"+letra+"%7c";
         System.out.println("Marcadores:");
         System.out.println(marcadores);
        
         
     }

      /**
       * agrega un marcador azul al string de marcadores
       * @param latitud latitud del marcador
       * @param longitud longitud del marcador
       * @param letra letra a mostrar en el marcador, también puede ser un número.
       */
     public void agregarMarcadorAzul(double latitud, double longitud, char letra){
         if(!hayMarcadores){
             marcadores="&markers=";
             hayMarcadores=true;
         }

         marcadores+= latitud+","+longitud+","+"blue"+letra+"|";
         System.out.println("Marcadores:");
         System.out.println(marcadores);

     }

       /**
       * agrega un marcador Amarillo al string de marcadores
       * @param latitud latitud del marcador
       * @param longitud longitud del marcador
       * @param letra letra a mostrar en el marcador, también puede ser un número.
       */
     public void agregarMarcadorAmarillo(double latitud, double longitud, char letra){
         if(!hayMarcadores){
             marcadores="&markers=";
             hayMarcadores=true;
         }

         marcadores+= latitud+","+longitud+","+"yellow"+letra+"%7c";
         System.out.println("Marcadores:");
         System.out.println(marcadores);

     }

     public double[] geocodeAddress(String address) throws Exception {
        byte[] res = loadHttpFile(getGeocodeUrl(address));
        String[] data = split(new String(res), ',');

        if (!data[0].equals("200")) {
            int errorCode = Integer.parseInt(data[0]);
            throw new Exception("Google Maps Exception: " + getGeocodeError(errorCode));
        }

        return new double[] {
                Double.parseDouble(data[2]), Double.parseDouble(data[3])
        };
    }

      public Image retrieveStaticImage(int width, int height, double lat, double lng, int zoom,
            String format, String tipoMapa) throws IOException {
          String url = getMapUrl(width, height, lng, lat, zoom, format,  tipoMapa);
          //String url2= "http://maps.google.com/maps/ms?ie=UTF8&hl=es&source=embed&msa=0&msid=112662661233841368429.0004705a6170a0b4a8f62&ll=4.664999,-74.14879&spn=0.164249,0.219727&z=12";
        byte[] imageData = loadHttpFile(url);
        System.out.println(url);
        System.out.println("Tamaño Imagen:");
        System.out.println(imageData.length);

        return Image.createImage(imageData, 0, imageData.length);
    }

      private static String getGeocodeError(int errorCode) {
        switch (errorCode) {
        case 400:
            return "Bad request";
        case 500:
            return "Server error";
        case 601:
            return "Missing query";
        case 602:
            return "Unknown address";
        case 603:
            return "Unavailable address";
        case 604:
            return "Unknown directions";
        case 610:
            return "Bad API key";
        case 620:
            return "Too many queries";
        default:
            return "Generic error";
        }
    }

       private String getGeocodeUrl(String address) {
        return "http://maps.google.com/maps/geo?q=" + urlEncode(address) + "&output=csv&key="
                + apiKey;
    }

        private String getMapUrl(int width, int height, double lng, double lat, int zoom, String format, String tipoMapa) {
        return "http://maps.google.com/staticmap?center=" + lat + "," + lng + "&format="
                + format + "&zoom=" + zoom + "&size=" + width + "x" + height +  "&maptype="+ tipoMapa + "&key=" + apiKey + marcadores+rutas;
    }

         private static String urlEncode(String str) {
        StringBuffer buf = new StringBuffer();
        byte[] bytes = null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(bos);
            dos.writeUTF(str);
            bytes = bos.toByteArray();
        } catch (IOException e) {
            // ignore
        }
        for (int i = 2; i < bytes.length; i++) {
            byte b = bytes[i];
            if (URL_UNRESERVED.indexOf(b) >= 0) {
                buf.append((char) b);
            } else {
                buf.append('%').append(HEX[(b >> 4) & 0x0f]).append(HEX[b & 0x0f]);
            }
        }
        return buf.toString();
    }

         
   private static byte[] loadHttpFile(String url) throws IOException {
        byte[] byteBuffer;

        HttpConnection hc = (HttpConnection) Connector.open(url);
        try {
            hc.setRequestMethod(HttpConnection.GET);
            InputStream is = hc.openInputStream();
            try {
                int len = (int) hc.getLength();
                if (len > 0) {
                    byteBuffer = new byte[len];
                    int done = 0;
                    while (done < len) {
                        done += is.read(byteBuffer, done, len - done);
                    }
                } else {
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[512];
                    int count;
                    while ( (count = is.read(buffer)) >= 0 ) {
                        bos.write(buffer, 0, count);
                    }
                    byteBuffer = bos.toByteArray();
                }
            } finally {
                is.close();
            }
        } finally {
            hc.close();
        }

        return byteBuffer;
    }

    private static String[] split(String s, int chr) {
        Vector res = new Vector();

        int curr;
        int prev = 0;

        while ( (curr = s.indexOf(chr, prev)) >= 0 ) {
            res.addElement(s.substring(prev, curr));
            prev = curr + 1;
        }
        res.addElement(s.substring(prev));

        String[] splitted = new String[res.size()];
        res.copyInto(splitted);

        return splitted;
    } 

}
